package com.whately.core.database.common.config;

import com.whately.core.database.db.DatabaseCfgConstant;
import com.whately.core.database.common.constant.WhatelyDbConstant;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionManager;
import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
import org.springframework.transaction.interceptor.RollbackRuleAttribute;
import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;
import org.springframework.transaction.interceptor.TransactionAttribute;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 事务拦截
 * 开启事务
 */
@Configuration
public class WhatelyTx4SequenceAspect {

    /*****************************************************************************
     * 构造切面
     ****************************************************************************/
    @Bean
    public Advisor txAdviceAdvisor4SequenceOpenTx(TransactionManager platformTransactionManager) {
        String expressTx = "execution (public * com.whately.core.database.common.srv.CoreSequenceTxFactory.*(..))";
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression(expressTx);

        NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();

        /*当前存在事务就使用当前事务，当前不存在事务就创建一个新的事务*/
        RuleBasedTransactionAttribute requiredTx = new RuleBasedTransactionAttribute();
        requiredTx.setRollbackRules(Collections.singletonList(new RollbackRuleAttribute(Exception.class)));

        /*PROPAGATION_REQUIRED:事务隔离性为1，若当前存在事务，则加入该事务；如果当前没有事务，则创建一个新的事务。这是默认值。 */
        requiredTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        requiredTx.setTimeout(WhatelyDbConstant.TX_METHOD_TIMEOUT);//如果超过60秒，则回滚事务

        Map<String, TransactionAttribute> txMap = new LinkedHashMap<>();
        //正常事务
        //txMap.put("*OpenTx", requiredTx);
        txMap.put("*", requiredTx);

        source.setNameMap( txMap );

        //指定数据源
        String seqSchema = DatabaseCfgConstant.router(WhatelyDbConstant.DATABASE_COMMON_SEQ_DIC_MAPPERS[0]);


        SequenceTxWhatelyInterceptor txAdvice = new SequenceTxWhatelyInterceptor(WhatelyDbConstant.GLOBAL_SEQUENCE_INTERCEPTOR_OPEN_TX_NAME,platformTransactionManager, source,seqSchema);

        return new DefaultPointcutAdvisor(pointcut, txAdvice);
    }


    /*
    @Bean
    public Advisor txAdviceAdvisor4Sequence(TransactionManager platformTransactionManager) {
        String express_not_tx = "execution (public * com.whately.core.database.common.srv.CoreSequenceFactory.*(..))";
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression(express_not_tx);

        NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();

        RuleBasedTransactionAttribute requiredTx_Not_Support = new RuleBasedTransactionAttribute();
        requiredTx_Not_Support.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED);
        requiredTx_Not_Support.setRollbackRules(Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
        requiredTx_Not_Support.setTimeout(WhatelyTxConstant.TX_METHOD_TIMEOUT);//如果超过60秒，则回滚事务

        Map<String, TransactionAttribute> txMap = new LinkedHashMap<>();
        //不要事务
        txMap.put("*", requiredTx_Not_Support);

        source.setNameMap( txMap );
        WhatelyTxInterceptor txAdvice = new WhatelyTxInterceptor(WhatelyTxConstant.,platformTransactionManager, source,null);

        return new DefaultPointcutAdvisor(pointcut, txAdvice);
    }
    */


}
